﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Mvc;

using BlogPlat.Model;
using BlogPlat.Model.Abstract;
using BlogPlat.Model.Repositories;

namespace BlogPlat.Areas.Admin.Controllers
{
    /// <summary>
    /// Admin Post Controller class
    /// </summary>
    [Authorize(Roles="admin,author")]
    public class PostController : Controller
    {
        /// <summary>
        /// Instance variable of type IPostRepository.        
        /// </summary>
        private IPostRepository _repository;

        /// <summary>
        /// A constructor that receive IPostRepository object as a parameter
        /// </summary>
        /// <param name="repository">Any object that implements IPostRepository</param>
        public PostController(IPostRepository repository) 
        {
            _repository = repository;
        }        

        /// <summary>
        /// This Index method lists all blog posts available for admin.     
        /// </summary>
        /// <returns>List of PostEntryModel object</returns>        
        public ActionResult Index()
        {            
            return View(_repository.List());
        }

        /// <summary>
        /// This method renders a form to create new post.
        /// </summary>
        /// <returns>ViewResult containing the form to create post.</returns>
        public ActionResult Create()
        {
            return View();
        }

        /// <summary>
        /// This method creates new Post in the database.   
        /// </summary>
        /// <param name="newPost">New post object.</param>
        /// <returns>A RedirectToRouteResult to redirect user to Index action to avoid double posting (PRG pattern).</returns>
        [AcceptVerbs(HttpVerbs.Post)]        
        public ActionResult Create(Post newPost)
        {
            if (ModelState.IsValid)
            {          
                // For testing purposes
                if(Server != null)
                    newPost.PostContent = Server.HtmlDecode(newPost.PostContent);

                newPost.FriendlyUrl = newPost.FriendlyUrl.Replace(" ", "-");
                newPost.FriendlyUrl = Regex.Replace(newPost.FriendlyUrl, "[\"$&+,/:;=?@]", String.Empty).ToLower();

                _repository.Add(newPost);

                // Do not forget to call this or else changes won't be submitted to database.
                _repository.Save();
                
                return RedirectToAction("Index");
            }

            return View();
        }

        /// <summary>
        /// Action method to delete a post.
        /// This action method is called using POST verbs.
        /// </summary>
        /// <param name="postID">Post ID to delete from database.</param>
        /// <returns>Returns RedirectToRouteResult object which redirect user back to Index action method to avoid double form posting (PRG pattern).</returns>        
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Delete(int postID)
        {            
            _repository.Delete(postID);
            _repository.Save();
            return RedirectToAction("Index");
        }

        /// <summary>
        /// Action method Edit to handle a POST request to edit a blog post.
        /// </summary>
        /// <param name="postToEdit">Post entity to update</param>
        /// <returns>Redirects to Index Action if success, if not takes the user back to the form.</returns>
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Edit(Post postToUpdate)
        {
            if (ModelState.IsValid)
            {                               
                postToUpdate.FriendlyUrl = postToUpdate.FriendlyUrl.Replace(" ", "-");
                postToUpdate.FriendlyUrl = Regex.Replace(postToUpdate.FriendlyUrl, "[\"$&+,/:;=?@]", String.Empty).ToLower();

                _repository.Update(postToUpdate);
                _repository.Save();

                return RedirectToAction("Index");
            }

            return View();
        }

        /// <summary>
        /// Action method that returns view to edit Post.      
        /// </summary>
        /// <param name="id">The ID of Post to edit</param> 
        /// <returns>View Results with model of type PostEntryModel.</returns>       
        public ActionResult Edit(int id)
        {
            Post postToEdit = _repository.Get(id);

            // For testing purposes
            if (Server != null)
                postToEdit.PostContent = Server.HtmlDecode(postToEdit.PostContent);

            return View(postToEdit);            
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        [ChildActionOnly]
        public string CurrentUser()
        {
            return HttpContext.User.Identity.Name;
        }
    }
}
